<?php
/**
 * 文件导出监控器
 * User: dxk
 * Date: 2020/08/05
 */
namespace App\Service\Core\Admin\File;

use App\Library\ThirdParty\DingTalk\DingTalkSendMsg;
use App\Model\Core\Admin\AdminFileModel;
use App\Service\Core\Service\Queue\QueueThread;

class AdminFileMonitorService extends QueueThread
{
    protected $max_pid_num = 6;
    protected $sleep_time = 3;

    protected function handle($file_id)
    {
        ini_set('memory_limit', '1024M');
        self::doLog('开始处理文件', ['file_id' => $file_id]);
        $res = $this->doHandle($file_id);
        self::doLog('结束处理文件', ['file_id' => $file_id, 'res' => $res]);
        return $res;
    }

    /**
     * 分发打包任务
     * @param $file_id
     * @return array
     */
    private function doHandle($file_id)
    {
        $file_id = (int)$file_id;
        //校验数据打包请求
        $FileService = AdminFileService::getInstance();
        $FileModel = AdminFileModel::getInstance();
        $connection = $FileModel->getConnection();
        $connection->beginTransaction();
        $file_info = $FileModel->getOne($file_id, false, true);
        if (empty($file_info)) {
            $connection->rollBack();
            return self::doEnd($file_id, 1, '请求不存在');
        }
        //开始下载
        $start_res = $FileService->startJob($file_id);
        if (!isset($start_res['code']) || $start_res['code'] !== 0) {
            $connection->rollBack();
            return self::doEnd($file_id, 1, $start_res['msg']);
        }
        $connection->commit();
        $handle = $file_info['handle'];
        try {
            $res = call_user_func([new $handle(), 'asyncExport'], $file_id);
        } catch (\Exception $e) {
            DingTalkSendMsg::sendErrorMsg(['handle' => $handle, 'tip' => '打包服务无法调起'], $e);
            return self::doEnd($file_id, 1, '打包服务无法调起' . $e->getMessage());
        }
        return self::doEnd($file_id, $res['code'], $res['msg'], $res['data']['file_path']);
    }

    /**
     * 分发结束
     * @param $file_id
     * @param $code
     * @param string $result
     * @param string $result_file_path
     * @return array
     */
    private function doEnd($file_id, $code, $result = '', $result_file_path = '')
    {
        $file_id = (int)$file_id;
        $status = AdminFileModel::STATUS_COMPLETE;
        if ($code != 0) {
            $status = AdminFileModel::STATUS_FAIL;
        }
        return AdminFileService::getInstance()->endJob($file_id, $status, $result, $result_file_path);
    }
}
